unit DataTable;

interface
uses DB,DBClient,MidasLib,Classes,Generics.Collections,SysUtils;

type TFilterParams=record
    FilterOptions:TFilterOptions;
    Filter:string;
    Filtered:boolean;
end;

type TDataTable=class(TClientDataSet)
  private
    FSavedRecNos:TStack<integer>;
    FSavedBookmarks:TStack<TBytes>;
    FBackupedFilterParams:TStack<TFilterParams>;
    FPrevRecNo:integer;
    FIndexFieldNamesForSort:string;

    procedure RecordBeforeScroll(DataSet:TDataSet);

    property SavedRecNos:TStack<integer> read FSavedRecNos write FSavedRecNos;
    property SavedBookmarks:TStack<TBytes> read FSavedBookmarks write FSavedBookmarks;
  protected
    property BackupedFilterParams:TStack<TFilterParams> read FBackupedFilterParams write FBackupedFilterParams;
    property IndexFieldNamesForSort:string read FIndexFieldNamesForSort write FIndexFieldNamesForSort;

    procedure Initialize;virtual;
    procedure Finalize;virtual;
  public
    procedure Clear;
    procedure CreateDataTable;
    procedure RememberPosition;
    procedure ReturnRememberedPosition;
    procedure RememberBookmark;
    procedure ReturnRememberedBookmark;
    procedure BackupFilter;
    procedure RestoreFilter;
    procedure ClearFilter;
    function GetAllRecNos:TList<integer>;

    procedure EnableIndexFieldNames;
    procedure DisableIndexFieldNames;

    procedure CopyFrom(source:TDataSet);

    constructor Create(AOwner: TComponent); override;
    destructor Destroy;override;

    //property Rows[rowIndex:integer]:TFields read getRows;
    //property PrevRecNo:integer read FPrevRecNo;
end;

implementation

{ DataType }

constructor TDataTable.Create(AOwner: TComponent);
begin
    inherited;
    FSavedRecNos:=TStack<integer>.Create;
    FSavedBookmarks:=TStack<TBytes>.Create;
    FBackupedFilterParams:=TStack<TFilterParams>.Create;
    //BackupFilter;
    FPrevRecNo:=-1;
    self.BeforeScroll:=RecordBeforeScroll;

    Initialize;
end;

destructor TDataTable.Destroy;
begin
    FSavedRecNos.Free;
    FSavedBookmarks.Free;
    FBackupedFilterParams.Free;
    inherited;

    Finalize;
end;

procedure TDataTable.EnableIndexFieldNames;
begin
    self.IndexFieldNames:=FIndexFieldNamesForSort;
    self.IndexDefs.Add('idxIndexField',FIndexFieldNamesForSort,[]);
end;

procedure TDataTable.DisableIndexFieldNames;
begin
    self.IndexFieldNames:='';
    self.IndexDefs.Clear;
end;

procedure TDataTable.RecordBeforeScroll(DataSet: TDataSet);
begin
    FPrevRecNo:=self.RecNo;
end;

procedure TDataTable.Clear;
begin
    self.EmptyDataSet;
end;

procedure TDataTable.CreateDataTable;
begin
    self.CreateDataSet;
end;

{function TDataTable.getRows(rowIndex: integer): TFields;
begin
    self.RecNo:=rowIndex+1;
    exit(self.Fields);
end;}

procedure TDataTable.RememberPosition;
begin
    SavedRecNos.Push(self.RecNo);
end;

procedure TDataTable.ReturnRememberedPosition;
var
    savedRecNo:integer;
begin
    savedRecNo:=SavedRecNos.Pop;
    if (1<=savedRecNo) and (savedRecNo<=self.RecordCount) then self.RecNo:=savedRecNo;
end;

procedure TDataTable.RememberBookmark;
begin
    SavedBookmarks.Push(self.Bookmark);
end;

procedure TDataTable.ReturnRememberedBookmark;
begin
    self.Bookmark:=SavedBookmarks.Pop;
end;

procedure TDataTable.BackupFilter;
var
    params:TFilterParams;
begin
    params.FilterOptions:=self.FilterOptions;
    params.Filter:=self.Filter;
    params.Filtered:=self.Filtered;
    BackupedFilterParams.Push(params);
end;

procedure TDataTable.RestoreFilter;
var
    params:TFilterParams;
begin
    params:=BackupedFilterParams.Pop;

    self.FilterOptions:=params.FilterOptions;
    self.Filter:=params.Filter;
    self.Filtered:=params.Filtered;
end;

procedure TDataTable.ClearFilter;
begin
    self.Filter:='';
    self.FilterOptions:=[];
    self.Filtered:=false;
end;

function TDataTable.GetAllRecNos: TList<integer>;
var
    recNos:TList<integer>;
begin
    recNos:=TList<integer>.Create;

    DisableControls;
    RememberPosition;

    First;
    while not EOF do begin
        recNos.Add(RecNo);
        Next;
    end;
    Result:=recNos;

    ReturnRememberedPosition;
    EnableControls;
end;

procedure TDataTable.CopyFrom(source: TDataSet);
var
    cds:TClientDataSet;
begin
    cds:=source as TClientDataSet;
    if cds<>nil then begin
        self.Data:=cds.Data;
    end;
end;

procedure TDataTable.Initialize;
begin

end;

procedure TDataTable.Finalize;
begin

end;

end.
